// package: rewords-server-2024
// filename: apiCtrl
// author: diogoxiang@gmail.com
// time: 2025/2/11 17:32

package aiCtrl

import (
	"context"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"go.mongodb.org/mongo-driver/bson"

	"rewords-server-2024/api/aiAPI"
	"rewords-server-2024/internal/consts"
	"rewords-server-2024/internal/library/ahttp"
	"rewords-server-2024/internal/library/ecode"
	"rewords-server-2024/internal/model/entity"
	"rewords-server-2024/internal/model/input/chat_in"
	"rewords-server-2024/internal/service"
)

// AiCtrl is the controller for the AI related operations.
var AiCtrl = new(cAiCtrl)

// cAiCtrl is the controller for the AI related operations.
type cAiCtrl struct{}

func (c *cAiCtrl) ChatTxt(ctx context.Context, req *aiAPI.ChatTxtReq) (res *aiAPI.ChatTxtRes, err error) {

	selectMap := bson.M{
		"id": req.Mid,
	}
	modelResult, err := service.Mgx().FindOne(ctx, consts.CAiSet, selectMap, nil)

	if err != nil {
		g.Log().Error(ctx, "FindOne error:", err)
		return nil, gerror.NewCode(ecode.InvalidParams)
	}
	g.Log().Info(ctx, modelResult)
	var modeInfo entity.SysAiModel
	var chatInp chat_in.RequestInp

	if err = gconv.Struct(modelResult, &modeInfo); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	if err = gconv.Struct(modeInfo.Info, &chatInp); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	sling := ahttp.New()

	successRes := new(chat_in.ResponseRes)
	errorRes := new(entity.ChatResErr)

	chatInp.Messages = req.Messages

	resp, err := sling.New().Add("Authorization", "Bearer "+modeInfo.ApiKey).
		Add("Content-Type", "application/json").
		Post(modeInfo.Url).
		BodyJSON(&chatInp).
		Receive(successRes, errorRes)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != 200 {
		return nil, err
	}

	res = &aiAPI.ChatTxtRes{
		Choice: successRes.Choices[0],
	}

	// 存储日志
	service.Mgx().InsertOne(ctx, consts.CAiModelLog, entity.SysAiModelLog{
		Id:       successRes.ID,
		Name:     modeInfo.Name,
		ApiKey:   modeInfo.ApiKey,
		InToken:  successRes.Usage.PromptTokens,
		OutToken: successRes.Usage.CompletionTokens,
		Remark:   "",
	})

	//g.Log().Info(ctx, successRes)
	//modelContext := contexts.Get(ctx)
	//g.Log().Info(ctx, modelContext)

	return
}
